import { Component, Input, OnChanges, OnInit, SimpleChanges } from '@angular/core';
import { FormBuilder, FormControl, FormGroup, Validators } from '@angular/forms';
import { ProductCate } from 'src/app/model/proudctCate';
import { ProductAttributeCateServiceApi } from 'src/app/api/product-attribute-cate-api.service';
import { CastcaderOpitonItem } from 'src/app/model/cascaderOptions';
import { ProductAttributeCategory } from 'src/app/model/productAttr';
import { FileUploder } from 'src/app/utils/file-uploder';
import { FileApiService } from 'src/app/api/file-api.service';
import { NzMessageService } from 'ng-zorro-antd/message';
import { environment } from 'src/environments/environment';
import { FileExtraData } from 'src/app/model/fileExtraData';
import { ProductCategoryApiService } from 'src/app/api/product-category-api.service';

@Component({
  selector: 'app-product-cate-detial',
  templateUrl: './product-cate-detial.component.html',
  styleUrls: ['./product-cate-detial.component.less', '../../../../styles/container.css']
})
export class ProductCateDetialComponent implements OnInit, OnChanges {

  @Input() category: ProductCate;
  categoryForm: FormGroup;
  upLevelCateOption = new Array<{ label: string, value: number }>();
  filterAttribute = new Array<{ id: number, controlName: string }>();
  filterOptions = new Array<CastcaderOpitonItem>();
  cateLogoFileUploader: FileUploder;
  fileUploadURL = environment.fileUploadURL;
  productAttributeIdList: Array<number>;

  constructor(
    private fb: FormBuilder,
    private attrCateApi: ProductAttributeCateServiceApi,
    private cateApi: ProductCategoryApiService,
    private fileApi: FileApiService,
    private message: NzMessageService,
  ) {
    this.cateLogoFileUploader = new FileUploder(this.fileApi, this.message);
    this.categoryForm = this.fb.group({
      description: [],
      icon: [],
      keywords: [],
      name: ['', [Validators.required]],
      navStatus: [0],
      parentId: [0],
      productUnit: [],
      showStatus: [0],
      sort: [0, [Validators.pattern('[0-9]*')]],
    })
  }

  ngOnChanges(changes: SimpleChanges): void {
    const currentCate = changes['category'].currentValue;
    this.cateLogoFileUploader.init([currentCate.icon]);
    this.setFormValue(currentCate);
  }

  ngOnInit(): void {
    this.fetchUpLevelCateOption();
    this.fetchFilterOptions();
    if (!this.productAttributeIdList || this.productAttributeIdList.length < 1) {
      this.addField();
    }
  }

  get name() { return this.categoryForm.get('name') }

  submitForm() {
    for (const key in this.categoryForm.controls) {
      this.categoryForm.controls[key].markAsDirty();
      this.categoryForm.controls[key].updateValueAndValidity();
    }
    if (this.categoryForm.valid) {
      let formData = {};
      let idList = [];
      for (const key in this.categoryForm.value) {
        if (Object.prototype.hasOwnProperty.call(this.categoryForm.value, key)) {
          if (key.includes('productAttributeIdList')) {
            if (this.categoryForm.value[key]) {
              idList.push(this.categoryForm.value[key][1]);
            }
          } else {
            formData[key] = this.categoryForm.value[key];
          }
        }
      }
      formData['productAttributeIdList'] = idList;
      console.log(formData);
      if (this.category?.id) {
        this.cateApi.update(this.category.id, <ProductCate>formData).subscribe(
          item => {
            this.message.success("分类修改成功")
          },
          err => {
            this.message.error("分类修改错误");
            console.error(err);
          }
        );
      } else {
        this.cateApi.create(<ProductCate>formData).subscribe(
          item => {
            this.message.success("分类创建成功")
          },
          err => {
            this.message.error("分类创建错误");
            console.error(err);
          }
        );
      }
    }
  }

  handleReset() {
    this.cateLogoFileUploader.rest();
    this.restForm();
  }

  restForm() {
    this.cateLogoFileUploader.fileList = [];
    this.filterAttribute = [];
    this.categoryForm = this.fb.group({
      description: [],
      icon: [],
      keywords: [],
      name: ['', [Validators.required]],
      navStatus: [0],
      parentId: [0],
      productUnit: [],
      showStatus: [0],
      sort: [0, [Validators.pattern('[0-9]*')]],
    })
    this.addField();
    for (const key in this.categoryForm.controls) {
      this.categoryForm.controls[key].markAsPristine();
      this.categoryForm.controls[key].updateValueAndValidity();
    }
  }

  handlelogoFileChange(e) {
    if (e.type == "success") {
      this.categoryForm.get('icon').setValue(e.file.response?.data.url);
      !this.category?.id || this.submitForm();

    }
    if (e.type == "removed") {
      this.categoryForm.get('icon').setValue(null);
      !this.category?.id || this.submitForm();
    }
  }

  getLogoExtraData = () => {
    return new FileExtraData('productCategory', this.categoryForm.get('name').value, 'icon');
  }

  addField(e?: MouseEvent, formValue?: Array<number>) {
    if (e) {
      e.preventDefault();
    }
    const id = this.filterAttribute.length > 0 ? this.filterAttribute[this.filterAttribute.length - 1].id + 1 : 0;
    const control = { id, controlName: `productAttributeIdList${id}` };
    const index = this.filterAttribute.push(control);
    this.categoryForm.addControl(this.filterAttribute[index - 1].controlName, new FormControl(formValue))
  }

  removeField(control: { id: number, controlName: string }, e: MouseEvent) {
    if (this.filterAttribute.length > 1) {
      const index = this.filterAttribute.indexOf(control);
      this.filterAttribute.splice(index, 1);
      this.categoryForm.removeControl(control.controlName);
    }

  }

  private fetchUpLevelCateOption() {
    this.cateApi.fetchAllInParent(0).subscribe(
      item => {
        this.upLevelCateOption = item.map(cate => { return { label: cate.name, value: cate.id } });
      }
    )
  }

  private fetchFilterOptions() {
    this.attrCateApi.listWithAttr().subscribe(
      item => {
        if (item instanceof Array && item.length > 0) {
          this.filterOptions = this.converCategoryToOption(item);
          if(this.productAttributeIdList && this.productAttributeIdList.length > 0) {
            this.initFilterForm(this.productAttributeIdList);
          }
        }
      },
    )
  }

  private converCategoryToOption(cates: Array<ProductAttributeCategory>): Array<CastcaderOpitonItem> {
    let result = new Array<CastcaderOpitonItem>();
    for (const cate of cates) {
      let optionItem = new CastcaderOpitonItem();
      optionItem.label = cate.name;
      optionItem.value = cate.id;
      let paramList
      if (cate.productAttributeList && cate.productAttributeList.length > 0) {
        paramList = cate.productAttributeList.filter(attr => attr.type == 1);
      }
      if (paramList && paramList.length > 0) {
        optionItem.children = [];
        for (const attr of paramList) {
          let child = new CastcaderOpitonItem();
          child.label = attr.name;
          child.value = attr.id;
          child.isLeaf = true;
          optionItem.children.push(child);
        }
      } else {
        optionItem.isLeaf = true;
      }
      result.push(optionItem);
    }
    return result;
  }

  private setFormValue(source: ProductCate) {
    this.categoryForm.setValue({
      description: source.description,
      icon: source.icon,
      keywords: source.keywords,
      name: source.name,
      navStatus: source.navStatus,
      parentId: source.parentId,
      productUnit: source.productUnit,
      showStatus: source.showStatus,
      sort: source.sort
    })
    if (source.productAttributeIdList && source.productAttributeIdList.length > 0) {
      this.productAttributeIdList = source.productAttributeIdList;
      if (this.filterOptions && this.filterOptions.length > 0) {
        this.initFilterForm(source.productAttributeIdList);
      }
    }
  }

  private initFilterForm(attrIdList: Array<number>) {
    for (const childId of attrIdList) {
      const cateItem = this.filterOptions.find(cate => cate.children.some(child => child.value == childId));
      const formValue = [cateItem.value, childId];
      this.addField(null, formValue);
    }
  }
}
